

#include "resourceLocator.h"
#include "core/exception/z3dException.h"
#include "core/utils/stringHelper.h"
#include "vfs/vfs.h"

using z3d::core::StringHelper;

namespace z3d{
	namespace utils{
		void ResourceLocator::init(){
                    // crear una copia del location path para trabajar mas
                    // comodo
                    std::string myPath = extractProtocol(_pathLocation);
                   
                    myPath = extractUserAndPassword(myPath);
                    
                    // despues seleccionamos host
                    // del host separamos el puerto si tiene
                    myPath = extractHostAndPort(myPath);
                    
                    // y finalmente seleccionamos el path
                    extractPath(myPath);
                    
		}
                std::string ResourceLocator::extractProtocol(const std::string& path){
                    // extraer el protocolo
                    std::string result = StringHelper::getSubstr("","://", path);
                    if(result.length() == 0)
                    {
                        std::stringstream ss;
                        ss << "Resource " + _pathLocation + " hasn't been defined correctly at protocol chunk";
                        THROW_AND_LOG(VFS_APPENDER, z3d::core::resourceIncorrectFormatException, ss.str());
                        return "";
                    }
                    _protocol = result;
                    return StringHelper::getSubstr("://", "", path);
                }
                
                std::string ResourceLocator::extractUserAndPassword(const std::string& path){
                    if(path.length() == 0)
                    {
                        THROW_AND_LOG(VFS_APPENDER, z3d::core::resourceIncorrectFormatException, "Path is empty, maybe because an error" );
                        return "";
                    }
                    std::string result = StringHelper::getSubstr("", "@", path);
                    if(result.length() == 0)
                    {
                        _log.WARNING_MSG(VFS_APPENDER, "Path location %s has been set without user or password", _pathLocation.c_str());
                        return path;
                    }else
                    {
                        // es importante buscar los : solo si aparece una @, por que
                        // el puerto se separa del host con : y podria ser desastroso.
                        _user= StringHelper::getSubstr("", ":", result);
                        if(_user.length() == 0 && result.find(":") == std::string::npos)
                        {
                            _password = result;
                        }else{
                            _password = StringHelper::getSubstr(":", "", result);
                        }
                        return StringHelper::getSubstr("@", "", path);
                    }
                    
                }
                
                std::string ResourceLocator::extractHostAndPort(const std::string& path){
                    if(path.length() == 0)
                    {
                        THROW_AND_LOG(VFS_APPENDER, z3d::core::resourceIncorrectFormatException, "Path is empty, maybe because an error" );
                        return "";
                    }
                    std::string result = StringHelper::getSubstr("", "/", path);
                    // no host + port is present?
                    if(result.length() == 0){
                        return path;
                    }
                    // if not ":" char has been found, then no port is present
                    std::string h = StringHelper::getSubstr("", ":", result);
                    if(h.length() == 0){
                        _host = result;
                    }else{
                        _host = h;
                        _port = StringHelper::getSubstr(":", "", result);
                    }
                    return StringHelper::getSubstr("/", "", path);
                }
                
                std::string ResourceLocator::extractPath(const std::string& path){
                    _path = path;
                    return "";
                }
                
                const std::string ResourceLocator::getProtocol() const{
                    return _protocol;
                }
                
                const std::string ResourceLocator::getUserName() const{
                    return _user;
                }
                
                const std::string ResourceLocator::getPassword() const{
                    return _password;
                }
                
                const std::string ResourceLocator::getHost() const{
                    return _host;
                }
                
                const std::string ResourceLocator::getPort()const{
                    return _port;
                }
                
                const std::string ResourceLocator::getPath() const{
                    return _path;
                }
	}
}